package src; /**
 * Created by imyar on 19/1/7.
 */

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

import java.io.IOException;
import java.util.Iterator;
import java.util.StringTokenizer;

public class AveScore {

    public static class TokenizerMapper
            extends Mapper<Object, Text, Text, IntWritable> {

        @Override
        public void map(Object key, Text value, Context context
        ) throws IOException, InterruptedException {
            //将输入的数据按行分割
            StringTokenizer itr = new StringTokenizer(value.toString(), "\n");
            //分别对每一行进行处理
            while (itr.hasMoreTokens()) {
                //按#号分割，默认为空格
                StringTokenizer itr1 = new StringTokenizer(itr.nextToken(), "#");
                String strName = itr1.nextToken();//姓名
                String strScore1 = itr1.nextToken();//语文成绩
                String strScore2 = itr1.nextToken();//数学成绩
                String strScore3= itr1.nextToken();//英语成绩
                Text name = new Text(strName);
                int scoreInt1= Integer.parseInt(strScore1);
                int scoreInt2 = Integer.parseInt(strScore2);
                int scoreInt3 = Integer.parseInt(strScore3);
                context.write(name, new IntWritable(scoreInt1));
                context.write(name, new IntWritable(scoreInt2));
                context.write(name, new IntWritable(scoreInt3));
            }
        }
    }

    public static class IntSumReducer
            extends Reducer<Text, IntWritable, Text, IntWritable> {

        @Override
        public void reduce(Text key, Iterable<IntWritable> values,
                           Context context
        ) throws IOException, InterruptedException {
            int count = 0;
            int sum = 0;
            Iterator<IntWritable> iterator = values.iterator();
            while (iterator.hasNext()) {
                sum += iterator.next().get();
                count++;
            }
            int average = (int) sum / count;//平均成绩
            context.write(key, new IntWritable(average));
        }
    }

    public static void main(String[] args) throws Exception {
        Configuration configuration = new Configuration();
        configuration.set("dfs.client.use.datanode.hostname", "true");
//        configuration.set("fs.defaultFS", "hdfs://hadoop-master:9000");//主机名访问
        configuration.set("fs.defaultFS", "hdfs://hadoop-master:9000");
        configuration.set("dfs.nameservices", "mycluster");
        configuration.set("dfs.ha.namenodes.mycluster", "nn1");
        configuration.set("dfs.namenode.rpc-address.mycluster.nn1", "hadoop-master:9000");
        configuration.set("dfs.client.failover.proxy.provider.mycluster",
                "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider");

        Job job = Job.getInstance(configuration, "word count");
        job.setJarByClass(AveScore.class);
        job.setMapperClass(TokenizerMapper.class);
        job.setCombinerClass(IntSumReducer.class);
        job.setReducerClass(IntSumReducer.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);

        // 判断output文件夹是否存在，如果存在则删除
        Path path = new Path(args[1]);// 取第1个表示输出目录参数（第0个参数是输入目录）
        FileSystem fileSystem = FileSystem.get(configuration);
        if (fileSystem.exists(path)) {
            fileSystem.delete(path, true);// true的意思是，就算output有东西，也一带删除
        }


        FileInputFormat.addInputPath(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));
        System.exit(job.waitForCompletion(true) ? 0 : 1);
    }
}